home *** CD-ROM | disk | FTP | other *** search
/ Cubase Magazine 32 / Issue #32.iso / 3-TUTORIAL / TRIANTI / convoluzione / convolver.c < prev    next >
C/C++ Source or Header  |  2001-02-17  |  2KB  |  108 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "convolver.h"
  4.  
  5. struct Convolver
  6. {
  7.     float* x;    /* buffer circolare (delay) contenente il segnale */
  8.     int N;        /* dimensione del delay e dell'impulso */
  9.  
  10.     float* h;    /* risposta all'impulso */    
  11.     int i;        /* indice (del delay) da cui la lettura del segnale ha origine */
  12.  
  13. } typedef Convolver;
  14.  
  15.  
  16. /*---------------------------------------------------------------
  17.    Crea una struttura per la convoluzione. 
  18. ---------------------------------------------------------------*/
  19. Convolver* Convolver_Crea (int N, float* h)
  20. {
  21.     Convolver* c;
  22.  
  23.     /* acquisisce memoria per un convolver */
  24.     c = malloc(sizeof(Convolver));
  25.     if (c == NULL) goto cleanup;
  26.  
  27.     /* azzera la struttura */
  28.     memset(c, 0, sizeof(*c));
  29.  
  30.     /* crea un buffer di delay e lo azzera */
  31.     c->x = malloc (sizeof(float)*N);
  32.     if (c->x == NULL) goto cleanup;
  33.     memset(c->x, 0, sizeof(float)*N);
  34.  
  35.     /* acquisisce memoria per copiare la risposta all'impulso
  36.        e copia quella passata alla funzione nel buffer appena
  37.        creato */
  38.     c->h = malloc (sizeof(float)*N);
  39.     if (c->h == NULL) goto cleanup;
  40.     memcpy (c->h, h, sizeof(float)*N);
  41.  
  42.     return c;
  43.  
  44.     cleanup:
  45.     if (c)
  46.     {
  47.         if (c->x) free(c->x);
  48.         if (c->h) free(c->h);
  49.         free(c);
  50.     }
  51.     return 0;
  52. }
  53.  
  54.  
  55. /*---------------------------------------------------------------
  56.    Processa un campione
  57. ---------------------------------------------------------------*/
  58. float Convolver_ProcessSample (Convolver* conv, float sample)
  59. {
  60.     float acc = 0;    /* accumulatore */
  61.  
  62.     if (conv != 0)
  63.     {    
  64.         int n, i;
  65.         i = conv->i;    /* indice delay */
  66.     
  67.         for (n = 0; n < conv->N; n++)
  68.         {
  69.             float delay, impulse;
  70.             delay = conv->x[i];
  71.             impulse = conv->h[n];
  72.  
  73.             /* MAC */
  74.             acc += delay * impulse;
  75.  
  76.             /* legge dal delay il prossimo campione */
  77.             if (++i >= conv->N) i = 0;
  78.         }
  79.  
  80.         /* aggiorna il buffer di delay con il nuovo campione */
  81.         conv->x[conv->i] = sample;
  82.  
  83.         /* aggiorna l'indice del delay */
  84.         if (++conv->i >= conv->N) conv->i = 0;
  85.  
  86.         /* ritorna la somma tra prodotti tra l'impulso ed il segnale
  87.            contenuto nel delay */
  88.     }
  89.     return acc;
  90. }
  91.  
  92.  
  93. /*---------------------------------------------------------------
  94.    Distrugge la struttura per la convoluzione
  95. ---------------------------------------------------------------*/
  96. void Convolver_Distruggi (Convolver* conv)
  97. {
  98.     if (conv)
  99.     {    
  100.         if (conv->x)
  101.             free(conv->x);
  102.  
  103.         if (conv->h)
  104.             free(conv->h);
  105.  
  106.         free(conv);
  107.     }
  108. }